JSX 문법과 사용

✒️ 2025-05-28 09:35 내용 수정


JSX 문법

Javascript 문법의 확장으로 React에서 사용함

function test() {
	return (
		<div>
			<h1>React Test</h1>
		</div>
	)
}

const user = {
	firstName : 'Tony',
	lastName : 'Stark'
}

function nameFormat(user) {
	return user.firstName + ' ' + user.lastName;
}
let status = true;

function isTired(status) {
	if (status) {
		return <span>Go to sleep...</span>;
	} else {
		return <span>Play game!</span>;
	}
}
function App() {
	function drawRender() {
		let result = [];
		for(let i = 0; i < 10; i++) {
			result.push(<span key={i}></span>);
		}
	}

	return ( 
		<>
			drawRender();
			// <span key={0}></span> 부터 <span key={9}></span> 까지가 생성된다
		</>
	)
}
let box = <div className="box"></div>;

const user = {name:'Arther Morgan'}
let input = <input type="text" value={user.name}>{user.name}</input>
<p style={ {color:'red', fontSize:'30px'} }>

JSX 작성

1. 태그 작성

function App() {
	return(
		// retunr은 태그 1개만 가능
		<div className="container">
			// 태그 내용
		</div>
	)
}

2. 변수 선언

function App() {

	let test = '테스트'; // return 전에 선언
	let section = 'section';

	return(
		<div className={section}>
			<h1>{test}</h1>
		</div>
	)
}

3. 이벤트 추가

function App() {
	
	function test() {
		console.log('test');
	}
	
	return(
		<div>
			<h1> <span onClick={test}>Click Me!</span> </h1>
			<h1> <span onClick={() => {
				console.log('Click Me too!');
			}}>
			Click Me too!</span> 
			</h1>
		</div>
	)
}

4. useState

import {useState} from 'react'; // useState를 꼭 가져와야 한다.

function App() {

	let test = '테스트'; // 정적 내용, 잘 안바뀌는 내용
	// data, change 함수 순으로 작성
	let [data, changeFunction] = useState('0'); // 동적 내용, 자주 바뀌는 내용
	let [data2, changeFunction2] = useState(['값1', '값2', '값3']); // 배열도 가능하다

	return(
		<div>
			// '테스트'가 출력된다
			<h1>{test}</h1> 
			// data의 값인 0이 출력된다.
			<p>{data}</p>
			// data2(배열)의 각 요소 값이 출력된다.
			<p>{data2[0]}, {data2[1]}, {data2[2]}</p>
		</div>
	)
}
import {useState} from 'react';

function App() {

	let [likeHit, likeHitChange] = useState(0);
	
	function likeUp() { // 이벤트 처리 함수
		likeHitChange(likeHit++); // useState의 data를 변경시킬 함수
	}
	
	return(
		<div>
			<h1> <span onClick={likeUp}>👍</span> {likeHit} </h1>
		</div>
	)
}
/* eslint-disable */ 

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';

import {useState} from 'react';

function App() {
  
  let post = "2023년 개봉 영화"; // 정적 내용

  // 내용 변경이 자주 일어나는 부분은 state에 값을 담아서 처리한다.
  // UI 기능 개발, 사이트 동작 등 자주 변경되는 부분을 새로고침 없이 재 랜더링해준다.
  let [title, titleChange] = useState(['존 윅', '가디언즈 오브 갤럭시', '스파이더맨']); // 동적 내용, html 재랜더링
  let [likeHit, likeHitChange] = useState([0, 0, 0]);

  function likeUp(e) {
    let num = e.target.className; // 이벤트가 발생한 대상을 가져와 className을 읽어옴
    let copy = [...likeHit]; // likeHit이라는 데이터의 배열을 깊은 복사
    copy[num]++; // 배열의 특정 index 요소를 +1 수행
    // 이렇게 하면 각기 다른 likeHit 요소들이 따로 +1 된다.
    likeHitChange(copy); // function은 data 전체를 바꾸기 때문에 복사한 배열로 원본 배열 수정 적용
  }

  return (

    <div className="App">
      <header className="header">
        <div className="container">
          <h1 className="logo"><a href="#">BLOG</a></h1>
        </div>
      </header>

      <section className="sec blog">
      <div className="container">   
           
        <div class="row list">

          <div className="item">
            <h3> {title[0]} <span onClick={likeUp} className='0'>👍</span> {likeHit[0]} </h3>
            <p>{post}</p>
          </div>

          <div className="item">
          <h3>{title[1]} <span onClick={likeUp} className='1'>👍</span> {likeHit[1]} </h3>
            <p>{post}</p>
          </div>

          <div className="item">
          <h3>{title[2]} <span onClick={likeUp} className='2'>👍</span> {likeHit[2]} </h3>
            <p>{post}</p>
          </div>

        </div>
      </div>
      </section>

    </div>
  );
}

export default App;

5. 함수 선언 및 사용

function App() {
  let [detail, setDetail] = useState(false); // detail의 기본 상태는 false
  // onClick을 다른 곳에 추가하여 아래 Detail이 보이거나 안보이게 설정할 수 있다.

  return (
    <div className="App">
      <section className="sec">
	      <div className="container">
	        <div className='row'>
	          <h2>조회</h2>
	          {
	            // useState detail의 상태에 따라 보이거나 안보이게 설정
	            // <Detail></Detail>의 내용은 아래 함수의 return 값으로 반환되는 태그
	            (detail) ? <Detail></Detail>: null
	          }
	        </div>
	      </div>
      </section>
    </div>
  );
}

function Detail() { // 함수 이름과 태그 이름이 동일함
  return(
    <div className='detail'>
      <h3>제목</h3>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  );
}

6. props.children

function App() {
	return(
		<Title>새로운 타이틀</Title>
	)
}

function Title(props) {
	console.log(props.children); // "새로운 타이틀"
	return(
		{/* "새로운 타이틀"이 자동으로 들어간다 */}
		<h2 className="title">{props.children}</h2>
	)
}

기타 활용

  1. 반복되는 구문 처리 : Array 객체의 map 메소드를 사용하여 비슷한 내용의 태그를 반복문으로 처리하여 한 번에 출력할 수 있다.
/* eslint-disable */
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';

import  {useState} from 'react';

function App() {

  let post = '2024년 발매 게임';

  let [title, titleChange] = useState(['리썰 컴퍼니', '팰월드', '헬스테이트2', '라스트어포치']);
  let [likeHit, likeHitChange] = useState([0, 0, 0, 0]);
  let [detail, detailChange] = useState([false, false, false, false]);

  function likeUp(e) {
    let num = e.target.className; // 이 부분은 아래 활용 코드에서 더 간단하게 수정했다.
    let copy = [...likeHit];
    copy[num]++;
    likeHitChange(copy);
  }

  function detailSwap(e) {
    let num = e.target.className;
    let copy = [...detail];
    copy[num] = !copy[num];
    detailChange(copy);
  }

  return (
    <div className='App'>
      <header className='header'>
        <div className='container'>
          <h1 className='logo'><a href="#">BLOG</a></h1>
        </div>
      </header>

      <section className='section sec'>
        <div className='container'>
          <div className='row list'>
            {
              title.map((el, i) => { // map을 사용하여 배열의 요소와 인덱스로 새 배열을 반환
                return(
                // map을 사용하는 경우 자식 객체에 key가 필요하다는 로그가 뜬다.
                // key={구분값}으로 자식마다 key를 배정해준다.
                  <div key={i} className='item'>
                    <div key={i*10} className='info'>
                      <h3>
                        <span onClick={detailSwap} className={i}>{el}</span>
                        <span onClick={likeUp} className={i} style={{cursor:'pointer'}}>❤</span> {likeHit[i]}
                      </h3>
                      <p>{post}</p>
                    </div>
                    {
                      (detail[i]) ? <Detail></Detail> : null
                    }
                  </div>
                )
              })
            }
          </div>
        </div>
      </section>
    </div>
  );
}

function Detail() {
  return(
    <div className='detail'>
      <h3></h3>
      <p>날짜</p>
      <p>상세 내용</p>
    </div>
  )
}

export default App;
*{margin:0; padding:0; box-sizing: border-box;}
ul, ol, li{list-style: none;}
a{text-decoration: none;}

body{background-color: #efefef;}

.header{
  width: 100%; 
  padding: 30px 0;
  background-color: #444;
}

.header a{color:#fff;}

.sec{
  width: 100%;
  padding:50px 0;
}

.sec .item{
  margin: 20px 0; padding: 30px; 
  background-color: #fff;
  border-radius: 10px;
}

.detail{
  padding: 30px;
  background-color: #eee;
}
  1. function으로 만든 태그에 property를 만들어 데이터를 전달할 수 있다.
/* eslint-disable */
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';

import  {useState} from 'react';

function App() {

  let post = '2024년 발매 게임';

  let [title, titleChange] = useState(['리썰 컴퍼니', '팰월드', '헬다이버즈2', '라스트에폭']);
  // 새로 발매일과 관련된 배열을 만들어준다.
  let [date, dateChange] = useState(['2023-10-24', '2024-01-19', '2024-02-08', '2024-01-19', '2024-02-21']);
  let [likeHit, likeHitChange] = useState([0, 0, 0, 0]);
  let [detail, detailChange] = useState([false, false, false, false]);

  function likeUp(num) {
    let copy = [...likeHit];
    copy[num]++;
    likeHitChange(copy);
  }

  function detailSwap(num) {
    let copy = [...detail];
    copy[num] = !copy[num];
    detailChange(copy);
  }

  return (
    <div className='App'>
      <header className='header'>
        <div className='container'>
          <h1 className='logo'><a href="#">BLOG</a></h1>
        </div>
      </header>

      <section className='section sec'>
        <div className='container'>
          <div className='row list'>
            {
              title.map((el, i) => { // map을 사용하여 배열의 요소와 인덱스로 새 배열을 반환
                return(
                  <div key={i} className='item'>
                    <div key={i*10} className='info'>
                      <h3>
                        <span onClick={() => detailSwap(i)}>{el}</span> 
                        <span onClick={() => likeUp(i)} style={{cursor:'pointer'}}>❤</span> {likeHit[i]}
                      </h3>
                      <p>{post}</p>
                    </div>
                    { // <Detail>에 property를 추가하면 아래 function에서 받아와 사용할 수 있다.
                      (detail[i]) ? <Detail title={title} date={date} index={i}></Detail> : null
                    }
                  </div>
                )
              })
            }
          </div>
        </div>
      </section>
    </div>
  );
}

function Detail(props) {
  // <Detail>에서 작성한 property는 객체로, 아래처럼 가져올 수 있음
  let {title, date, index} = props;
  
  return(
    <div className='detail'>
      <h3>{title[index]}</h3>
      <p>{date[index]}</p>
      <p>상세 내용</p>
    </div>
  )
}

export default App;